/* ----------------------------------------------------------------------------
* File: main.h
*
* Desc: Main header file, contains all structures, defines and function definitions
*
* Created: 20/12/2010, by Alexey Korshunov
* ---------------------------------------------------------------------------- */
#pragma once

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
#endif						

#include <stdio.h>
#include <tchar.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <atlbase.h>
#include <atlcom.h>

#include <map>
#include <vector>
#include <list>

#include "utils.h"

#import "Skype4COM.dll" named_guids


/************************************************************************/
/* Returned codes                                                       */
/************************************************************************/
#define SKYPE_PLUG_OK				0
#define SKYPE_PLUG_ERROR			-1
#define SKYPE_PLUG_INVALID_ARG		-2
#define SKYPE_PLUG_ERROR_MEMORY		-3


/************************************************************************/
/* Sleep defines                                                        */
/************************************************************************/
#define SERVICE_SLEEP				100					// ms
#define SERVICE_SKYPE_ATTACH_SLEEP	1000				// ms
#define THREAD_CHAT_INIT_WAIT		1000				// 1 sec
#define THREAD_CHAT_TOPIC_SLEEP		1000 /** 3600 * 1*/		// 1 min
#define THREAD_CHAT_STAT_SLEEP		1000 /** 3600 * 5*/		// 5 min
#define THREAD_COMMANDS_SLEEP		1000



/************************************************************************/
/* Defines for threads                                                  */
/************************************************************************/
#define COUNT_THREADS				5
#define CHAT_TOPIC_THREAD_NUM		0
#define CHAT_STAT_THREAD_NUM		1
#define COMMANDS_THREAD_NUM			2
#define QUIZ_THREAD_NUM				3
#define QUIZ_TIMER_THREAD_NUM		4

class CSkypeEventListener;

/************************************************************************/
/* Structure for Skype info			                                    */
/************************************************************************/
typedef struct SkypeInfo
{
	SkypeInfo() : pSkype(NULL), pSinkSkype(NULL)
	{}

	~SkypeInfo()
	{}

	SKYPE4COMLib::ISkypePtr pSkype;		// pointer to a Skype object
	CSkypeEventListener* pSinkSkype;	// pointer to a Skype listener
	_bstr_t bstrSkypeVersion;		// Skype client version
	_bstr_t bstrWrapperVersion;		// COM wrapper version
}SkypeInfo;


/************************************************************************/
/* Structure for message info                                           */
/************************************************************************/
typedef struct MessageInfo
{
	MessageInfo() : 
Id(0),
msgStatus(SKYPE4COMLib::TChatMessageStatus::cmsUnknown),
msgType(SKYPE4COMLib::TChatMessageType::cmeUnknown) 
{}
~MessageInfo()
{}

long Id;
_bstr_t body;
SKYPE4COMLib::TChatMessageStatus msgStatus;
SKYPE4COMLib::TChatMessageType msgType;
DATE timeStamp;
}MessageInfo;


/************************************************************************/
/* Structure for Chat info			                                    */
/************************************************************************/
typedef struct ChatInfo
{
	typedef std::map<_bstr_t, std::vector<MessageInfo>>				MessagesMap;
	typedef std::map<_bstr_t, std::vector<MessageInfo>>::iterator	MessagesMapIterator;

	ChatInfo() : 
	pChat(NULL),
		countMembers(0),
		countMessages(0)
	{
		InitializeCriticalSection(&csMsg);
	}

	~ChatInfo()
	{
		DeleteCriticalSection(&csMsg);
		msgMap.clear();
	}

	SKYPE4COMLib::IChatPtr pChat;		// pointer to a Chat object

	// members info
	long countMembers;		// count of the members

	// messages info
	long countMessages;		// count of all messages for chat
	MessagesMap	msgMap;		// map for messages
	CRITICAL_SECTION csMsg;
}ChatInfo;


/************************************************************************/
/* Structure to describe settings of the plugin                         */
/************************************************************************/
typedef struct PluginSettings
{
	PluginSettings() : 
bChatTopicControl(false),
bChatStatControl(false),
bCommands(false),
bDiscuss(false),
bQuiz(false)
{}

~PluginSettings(){}

bool bChatTopicControl;
bool bChatStatControl;
bool bCommands;
bool bDiscuss;
bool bQuiz;
}PluginSettings;


/************************************************************************/
/* Enumeration for plugin commands                                      */
/************************************************************************/
typedef enum ePluginCommand
{
	pcUnknown = 0,
	pcChatTopicControl,
	pcChatStatControl,
	pcDiscuss
}ePluginCommand;


/************************************************************************/
/* Structure for plugin environment                                     */
/************************************************************************/
typedef struct SkypeEnv
{
	typedef std::list<MessageInfo>				CommandsList;
	typedef std::list<MessageInfo>::iterator	CommandsListIterator;

	SkypeEnv() : 
	hStatus(NULL), 
		bError(false),
		bStop(false),
		hStopEvent(NULL),
		pMarshalStreamInit(NULL)
	{
		memset(hStartThreadEvents, 0, sizeof(HANDLE) * COUNT_THREADS);
		memset(pMarshalStreams, 0, sizeof(IStream) * COUNT_THREADS);
		InitializeCriticalSection(&csCommands);
	}

	~SkypeEnv()
	{
		listCommands.clear();
		DeleteCriticalSection(&csCommands);
	}

	// Skype info
	SkypeInfo skypeInfo;

	// Chat info
	ChatInfo chatInfo;

	// Plugin settings
	PluginSettings settings;

	// Windows service info
	SERVICE_STATUS serviceStatus;
	SERVICE_STATUS_HANDLE hStatus;

	// Other
	std::fstream logFile;
	bool bError;
	bool bStop;
	HANDLE hStopEvent;

	// Thread events
	HANDLE hStartThreadEvents[COUNT_THREADS];
	IStream* pMarshalStreams[COUNT_THREADS];
	IStream* pMarshalStreamInit;

	// Commands queue
	CommandsList listCommands;
	CRITICAL_SECTION csCommands;

	// Quiz info
	std::string question_file;
	std::string user_file;
	HANDLE hTimerThread;
	HANDLE hTimerEvents[4];
	//HANDLE hStopEventTimer;
	//HANDLE hStartQuestion;
	//HANDLE hStopQuestion;
}SkypeEnv;


// win_service.cpp
int InstallWinService(TCHAR *servicePath);
int RemoveWinService(TCHAR *servicePath);
int StartWinService(TCHAR *servicePath);
int StopWinService(TCHAR *servicePath);
void ServiceInit();
void ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
void ServiceMain(int argc, char** argv);

// skype_service.cpp
int StartSkypeService(SC_HANDLE hSCManager);
int CreateSkypeService(SC_HANDLE hSCManager);


// skype_init.cpp
int InitSkypePlugin(SkypeEnv *pSkypeEnv, HANDLE *hThreads);
int DestroySkypePlugin(SkypeEnv *pSkypeEnv, HANDLE *hThreads);

// skype_chat.cpp
DWORD WINAPI ChatTopic(LPVOID lpParam);

// skype_chat_statistics.cpp
DWORD WINAPI ChatStat(LPVOID lpParam);

// skype_commands.cpp
DWORD WINAPI Commands(LPVOID lpParam);

// skype quiz
DWORD WINAPI QuizThread(LPVOID lpParam);
